MODULES ?= 
MODULES_CLEAN ?= 
PRE_MODULES ?=
POST_MODULES ?=
APPS ?=
APPS_CLEAN ?=

CROSS ?=
CC := $(CROSS)gcc
CXX := $(CROSS)g++
PLATFORM :=
HOST := 
.CC_PROG := $(notdir $(CC))
ifneq ($(findstring android,$(.CC_PROG)),)
	PLATFORM := android
  ifneq ($(findstring x86_64,$(.CC_PROG)),)
    ARCH := x86_64
  else ifneq ($(findstring i686,$(.CC_PROG)),)
    ARCH := x86
  else ifneq ($(findstring aarch64,$(.CC_PROG)),)
    ARCH := aarch64
    ifneq ($(findstring -march=armv8-a,$(CFLAGS)),)
    ARCH := arm64-v8a
    endif    
  else ifneq ($(findstring arm,$(.CC_PROG)),)
    ARCH := armeabi
    ifneq ($(findstring -march=armv7-a,$(CFLAGS)),)
    ARCH := armeabi-v7a
    endif
  else
    ARCH := mipsel
  endif
else ifeq ($(.CC_PROG),gcc) #linux
    PLATFORM := linux
else ifeq ($(.CC_PROG),cc)
    PLATFORM := linux
endif

ifneq (,$(findstring Linux,$(shell uname)))
HOST := linux
endif

ifeq ($(V),1)
Q=
else
Q=@
endif

module-name :=
module-cfiles :=

ifeq ($(DEBUG), 1)
DEBUG-CFLAGS := -g -O0
else
DEBUG-CFLAGS :=
endif
ROOTDIR := $(shell pwd)

#build-static := $(ROOTDIR)/config/ftr-build-static.mk

#func
define ftr-c2o
$(patsubst %.c,%.o,$1)
endef

define ftr-c2file
$(patsubst %.c,%,$($1))
endef

define ftr-module-name
$(notdir $(patsubst %.o,%,$1))
endef

define ftr-get-file-build-dir
$(patsubst $(ROOTDIR)/%,build/%,$(shell dirname $1))
endef

define ftr-get-file-dir
$(patsubst $(ROOTDIR)/%,%,$(shell dirname $1))
endef

define ftr-obj
$(1):$(2)
ifeq ($(DEBUG), 1)
	@echo [DEBUG] completing $(call ftr-get-file-dir,$(1))/$$(notdir $$@)
else
	@echo completing $(call ftr-get-file-dir,$(1))/$$(notdir $$@)
endif
	@mkdir -p $$(shell dirname $1)
	$(Q)$(CC) $(DEBUG-CFLAGS) $(CFLAGS) $(INCLUDE) $($(call ftr-module-name, $1)-cflags) \
    -DMODULE_NAME=$(call ftr-module-name, $1) -DMODULE_STRING="\"$(call ftr-module-name, $1)\"" -c -o $$@ $$< 

endef

define ftr-obj-in-builddir
$(call ftr-obj,$(ROOTDIR)/$(call ftr-get-file-build-dir, $1)/$(notdir $1),$2)
endef

define ftr-build-objs
$(foreach i,$($1-cfiles),$(call ftr-obj-in-builddir,\
                                $(call ftr-c2o,$(i)),\
                                $(i)) )
endef

define ftr-list-objs
$(call ftr-c2o,\
  $(foreach i,$($1-cfiles),$(ROOTDIR)/$(call ftr-get-file-build-dir, $(i))/$(notdir $(i)))\
  )
endef

.build-static-dir := build/$(PLATFORM)/$(ARCH)
.install-dir := install/$(PLATFORM)/$(ARCH)

define ftr-build-static
  #.$1-objs := $(call ftr-c2o,$($1-cfiles))
  .$1-objs := $(call ftr-list-objs,$1)
  $(1)-lib := $(.build-static-dir)/lib$(1).a
  $(call ftr-build-objs,$1)
  MODULES += $$($(1)-lib)
  MODULES_CLEAN += $(1)-clean
  $$($(1)-lib):$$(.$(1)-objs)
	@echo -e "\033[33m gen $$@...... \033[0m"
	@mkdir -p $(.build-static-dir)
	$(Q)ar r $$@ $$^
  $(1)-clean:
	@rm -rf $$($(1)-lib) $$(.$(1)-objs)

endef

define ftr-add-path
$1-cfiles := $(addprefix $(CURDIR)/,$($1-cfiles))
endef

build-static = $(eval $(call ftr-add-path,$1))$(eval $(call ftr-build-static,$1))
build-static-ex = $(eval $(module-name)-cfiles := $(module-cfiles))$(eval $(call ftr-add-path,$(module-name)))$(eval $(call ftr-build-static,$(module-name)))

define ftr-build-exec
  #.$1-objs := $(call ftr-c2o,$($1-cfiles))
  .$1-objs := $(call ftr-list-objs,$1)
  $(1)-app := $(.build-static-dir)/app-$(1)
  $(call ftr-build-objs,$1)
  APPS += $$($(1)-app)
  APPS_CLEAN += $(1)-app-clean
  $$($(1)-app):$$(.$(1)-objs) .modules 
	@echo -e "\033[33m gen $$@...... \033[0m"
	@mkdir -p $(.build-static-dir)
	$(Q)$(CXX) -O2 -o $$@ $$(.$(1)-objs) -Wl,--start-group $(LIBS) $(MODULES) -Wl,--end-group $(INCLUDE) $(CFLAGS) $(LDFLAGS)
  $(1)-app-clean:
	@rm -rf $$($(1)-lib) $$(.$(1)-objs)
endef

build-exec = $(eval $(module-name)-cfiles := $(module-cfiles))$(eval $(call ftr-add-path,$(module-name)))$(eval $(call ftr-build-exec,$(module-name)))

define ftr-build-so
  .$1-libs := $($1-libs)
  $(1)-so := $(.build-static-dir)/lib$(1).so
  APPS += $$($(1)-so)
  APPS_CLEAN += $(1)-so-clean
  $$($(1)-so):.modules $$(.$(1)-libs)
	@echo -e "\033[33m gen $$@...... \033[0m"
	@mkdir -p $(.build-static-dir)
ifeq ($($1-libs),)
	$(Q)$(CXX) -shared -O2 -o $$@ -Wl,--start-group $(LIBS) $(MODULES) -Wl,--end-group $(INCLUDE) $(CFLAGS) $(LDFLAGS)
else  
	$(Q)$(CXX) -shared -O2 -o $$@ $$(.$(1)-libs) -Wl,--start-group $(LIBS) $(MODULES) -Wl,--end-group $(INCLUDE) $(CFLAGS) $(LDFLAGS)
endif  
  $(1)-so-clean:
	@rm -rf $$($(1)-so)
endef
build-so = $(eval $(module-name)-cfiles := $(module-cfiles))$(eval $(call ftr-add-path,$(module-name)))$(eval $(call ftr-build-so,$(module-name)))

define ftr-install-so
APPS += .install-$(1)
.install-$(1):
	@echo -e "\033[33m install $(.install-dir)/lib$(1).so...... \033[0m"
	@mkdir -p $(.install-dir)
	@cp -vrf $(.build-static-dir)/lib$(1).so $(.install-dir)
endef
install-so = $(eval $(call ftr-install-so,$(module-name)))
